/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import org.aswing.ASWingUtils;
import org.aswing.border.Border;
import org.aswing.border.EmptyBorder;
import org.aswing.border.TitledBorder;
import org.aswing.BorderLayout;
import org.aswing.geom.Point;
import org.aswing.Insets;
import org.aswing.JButton;
import org.aswing.JComboBox;
import org.aswing.JFrame;
import org.aswing.JLabel;
import org.aswing.JPanel;
import org.aswing.SoftBoxLayout;

import fever.app.local.Culture;
import fever.app.local.Localisation;
import fever.app.local.LocalisationEvent;
import fever.app.local.LocalisationListener;
import fever.display.ModalScreen;
import fever.Fever;

import fvaswing.components.localchooser.FvLocalChooserResources;
import fvaswing.components.localchooser.FvLocalisationCellFactory;

/**
 * Chooser dialog to customize application language.
 * 
 * <p>Dialog is open in modal mode to avoid user interactions during 
 * customisation process.
 * 
 * <p>Modifications can be process at runtime or at application restart<br />
 * Using a SharedLocal object saved object.
 * 
 * <p>Use {@link #enabledRuntimeSwapping} property to define if runtime is enabled 
 * or not.
 * 
 * <p>Localisation system is only available using <strong>Fever configuration system</strong>
 *  
 * <p>Example
 * {@code
 *   FvLocalisationChooser.enabledRuntimeSwapping = true;
 *   FvLocalisationChooser.open();
 * }
 * 
 * @author Romain Ecarnot
 */
class fvaswing.components.FvLocalisationChooser implements LocalisationListener
{
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private static var _instance : FvLocalisationChooser;	
	private var _frame : JFrame;
	private var _list : JComboBox;
	private var _okButton : JButton;
	private var _cancelButton : JButton;
	private var _applyButton : JButton;
	private var _restartLabel : JLabel;
	private var _modal : ModalScreen;
	
	private var _panel : JPanel;	private var _stored : String;
	
	
	//-------------------------------------------------------------------------
	// Public Properties
	//-------------------------------------------------------------------------
	
	/** 
	 * Indicates if localisation can be apply at runtime or only at application 
	 * restart. Default is {@code true}.
	 */
	public static var  enabledRuntimeSwapping : Boolean = true;
	
	
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Returns {@link FvLocalisationChooser} instance.
	 */
	public static function getInstance() : FvLocalisationChooser
	{
		if( !_instance ) _instance = new FvLocalisationChooser();
		return _instance;	
	}
	
	/**
	 * Opens dialog.
	 */
	public function open() : Void
	{
		_getInstance()._openDialog();
	}
	
	public function onLocalisationUpdate( event : LocalisationEvent ) : Void
	{
		_okButton.setText( FvLocalChooserResources.getInstance().okLabel );
		_cancelButton.setText( FvLocalChooserResources.getInstance().cancelLabel );
		_applyButton.setText( FvLocalChooserResources.getInstance().applyLabel );
		_restartLabel.setText( FvLocalChooserResources.getInstance().restartMessage );
		
		_frame.setTitle(  FvLocalChooserResources.getInstance().title );
		_panel.setBorder( null );		_panel.setBorder( _buildTiledBorder( FvLocalChooserResources.getInstance().panelTitle ) );
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	/**
	 * Retreives singleton instance.
	 */
	private static function _getInstance(  ) : FvLocalisationChooser
	{
		if( !_instance ) _instance = new FvLocalisationChooser();
		return _instance;
	}
	
	/**
	 * Constructor.
	 */
	private function FvLocalisationChooser()
	{
		_configureUI();
		Localisation.addLocalisationListener( this );
	}
	
	/**
	 * Resets JList data and open dialog.
	 */
	private function _openDialog() : Void
	{
		if( !Localisation.isSupported() ) 
		{
			Fever.dialog.alert( 'No translation files are found.' );
			
			return;
		}
		
		_list.setListData( Localisation.getLocalisationList() );
		_list.setSelectedItem( Localisation.culture );
		_list.revalidateIfNecessary();
		
		_stored = Localisation.culture.id;
		
		onLocalisationUpdate();
		
		_restartLabel.setVisible( !enabledRuntimeSwapping );
		
		_layout();
		_modal.show();
		_frame.show();
	}
	
	/**
	 * Prepares dialog.
	 */
	private function _configureUI() : Void
	{
		_configureBasedFrame();
		
		_panel = _buildTiledPanel( "" );
		_panel.append( _getList(), BorderLayout.NORTH );
		
		_restartLabel = new JLabel( "" );
		
		var option : JPanel = new JPanel( new SoftBoxLayout( SoftBoxLayout.Y_AXIS, 5 ) );
		option.append( _panel );
		option.append( _restartLabel );
		
		var framePanel : JPanel = new JPanel( new BorderLayout( 5, 5 ) );
		framePanel.setBorder( new EmptyBorder( null, new Insets( 5, 5, 5, 5 ) ) );
		framePanel.append( option, BorderLayout.NORTH );
		framePanel.append( _getButtonPanel(), BorderLayout.SOUTH );
		
		_frame.getContentPane().append ( framePanel, BorderLayout.CENTER );
	}
	
	/**
	 * Configures the based {@code JFrame} container.
	 */
	private function _configureBasedFrame() : Void
	{
		_modal = new ModalScreen();
		
		_frame = new JFrame( _modal.getModalTarget(),"", false );
		_frame.setResizable( false );
		_frame.setClosable( false );
		_frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
		_frame.addEventListener( JFrame.ON_WINDOW_CLOSING, _handleClose, this );
	}
	
	/**
	 * Creates LAF Chooser list
	 */
	private function _getList() : JComboBox
	{
		_list = new JComboBox(  );
		_list.setListCellFactory( new FvLocalisationCellFactory() );
		return _list;	
	}
	
	private function _getButtonPanel() : JPanel
	{
		var w : Number = 100;
		
		_okButton = new JButton( "-" );
		_okButton.setPreferredWidth( w );
		_okButton.addActionListener( _handleOkButton, this );
		
		_cancelButton = new JButton( "-" );
		_cancelButton.setPreferredWidth( w );
		_cancelButton.addActionListener( _handleCancelButton, this );
		
		_applyButton = new JButton( "-" );
		_applyButton.setPreferredWidth( w );
		_applyButton.addActionListener( _handleApply, this );
		 
		var p : JPanel = new JPanel( new SoftBoxLayout( SoftBoxLayout.X_AXIS, 5, SoftBoxLayout.RIGHT ) );
		p.append( _okButton );
		p.append( _cancelButton );
		p.append( _applyButton );
		return p;
	}
	
	/**
	 * Calculates a new frame position
	 */
	private function _layout() : Void
	{
		_frame.pack();
		
		var location : Point = ASWingUtils.getScreenCenterPosition();
		location.x -= _frame.getWidth()/2;
		location.y -= _frame.getHeight()/2;
		_frame.setLocation( location );
	}
	
	/**
	 * Creates a new JPanel with TiledBorder
	 */
	private function _buildTiledPanel( caption ) : JPanel
	{
		var p : JPanel = new JPanel( new BorderLayout( 5, 5 ) );
		p.setBorder( _buildTiledBorder( caption ) );
		return p;
	}
	
	/**
	 * Creates a tiled border.
	 */
	private function _buildTiledBorder( caption : String ) : Border
	{
		return new TitledBorder( _buildInternalBorder(), caption, TitledBorder.TOP, TitledBorder.LEFT, 10 );	
	}
	
	/**
	 * Creates internal border on component
	 */
	private function _buildInternalBorder() : Border
	{
		return 	new EmptyBorder( null, new Insets( 0,10,5,10 ) );
	}
	
	/**
	 * Trigerred when user click on a button ( or default close button )
	 */
	private function _handleClose( button : JButton ) : Void
	{
		_modal.hide();
		_frame.tryToClose();
	}
	
	private function _handleCancelButton() : Void
	{
		_applySelectedLang( _stored );
		_handleClose();
	}

	private function _handleOkButton() : Void
	{
		_saveCookie( Culture( _list.getSelectedItem() ).id );
		_handleClose();
	}

	private function _handleApply() : Void
	{
		if( enabledRuntimeSwapping )
		{
			_applySelectedLang( Culture( _list.getSelectedItem() ).id );
		}
	}
	
	private function _applySelectedLang ( id : String ) : Void
	{
			Localisation.lang = id;
			
			_saveCookie( id );
	}
	
	private function _saveCookie( loc : String ) : Void
	{
		Fever.application.config.save( Localisation.CONFIG_ID, loc );
	}
}